package route

import (
	"encoding/json"
	"github.com/crazyhl/gopermission"
	"github.com/crazyhl/gopermission/config"
	"github.com/form3tech-oss/jwt-go"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	jwtware "github.com/gofiber/jwt/v2"
	permissionController "go-fiber-demo/controller/permission"
	ruleController "go-fiber-demo/controller/rule"
	"go-fiber-demo/controller/user"
	"go-fiber-demo/models"
	"go-fiber-demo/pkg"
	"go-fiber-demo/pkg/utils"
	"go-fiber-demo/pkg/utils/encoder/aes"
	"gorm.io/gorm/clause"
	"time"
)

func RegisterTestRoute() {
	app := pkg.GetConfig().App

	app.Use(cors.New(cors.Config{
		AllowOrigins: "http://localhost:8080",
	}))

	utils.AddClosedRequest(func(ctx *fiber.Ctx) error {
		// 每个请求前的处理器，这么做，而不采用官方的use 或者 middleware 方案是因为这样最接近请求，可以拿到准确的请求路由，方便后面判定
		userToken := ctx.Locals("user").(*jwt.Token)
		claims := userToken.Claims.(jwt.MapClaims)
		ext := claims["ext"].(float64)
		now := float64(time.Now().Unix())
		// ext 有效期过期
		if ext < now {
			return ctx.Status(401).SendString("非法访问7")
		}
		token := claims["token"].(string)
		if token == "" {
			return ctx.Status(401).SendString("非法访问1")
		}
		tokenStr := aes.CBCDecode(token)
		checkMap := make(map[string]interface{})
		err := json.Unmarshal([]byte(tokenStr), &checkMap)
		if err != nil {
			return ctx.Status(401).SendString("非法访问4")
		}
		uid := int(claims["uid"].(float64))
		if uid != int(checkMap["uid"].(float64)) {
			return ctx.Status(401).SendString("非法访问5")
		}
		// 查看用户是否存在
		loginUser := new(models.User)
		gormDb := config.GetConfig().GormDb
		gormDb.Preload(clause.Associations).Preload("Rules.Permissions").First(&loginUser, uid)
		if loginUser.ID == 0 {
			return ctx.Status(401).SendString("非法访问3")
		}
		// 把查到的用户放到 ctx 中
		ctx.Locals("loginUser", loginUser)
		ctx.Locals("uid", uid)
		ctx.Locals("isSuperUser", uid == pkg.GetConfig().SuperUid)

		requestRoutePath := ctx.Route().Path
		requestUri := string(ctx.Request().URI().Path())
		userFullPermissions := loginUser.FullPermissions()
		userMap := gopermission.StructToMap(loginUser)

		if uid != pkg.GetConfig().SuperUid && !gopermission.HasPermission(userMap, ctx.Route().Method, requestRoutePath, requestUri, userFullPermissions) {
			return ctx.Status(401).SendString("非法访问2")
		}

		return ctx.Next()
	})

	utils.PostWithoutClosedHandler(app, "/login", user.Login)
	//utils.PostWithoutClosedHandler(app, "/register", user.Register)

	adminRouter := app.Group("/admin", jwtware.New(jwtware.Config{
		SigningKey: []byte(pkg.GetConfig().JwtConfig.TokenSecret),
	}))

	ruleRouter := adminRouter.Group("/rules")
	utils.Get(ruleRouter, "/", ruleController.List)                                     // 角色列表
	utils.Post(ruleRouter, "/", ruleController.Add)                                     // 创建角色
	utils.Put(ruleRouter, "/:id", ruleController.Update)                                // 编辑角色
	utils.Delete(ruleRouter, "/:id", ruleController.Delete)                             // 删除角色
	utils.Get(ruleRouter, "/:id", ruleController.Detail)                                // 查看角色详情
	utils.Patch(ruleRouter, "/:id/attachPermissions", ruleController.AttachPermissions) // 角色绑定权限

	permissionRouter := adminRouter.Group("/permissions")
	utils.Post(permissionRouter, "/", permissionController.Add)         // 创建权限
	utils.Get(permissionRouter, "/", permissionController.List)         // 权限列表
	utils.Put(permissionRouter, "/:id", permissionController.Update)    // 编辑权限
	utils.Delete(permissionRouter, "/:id", permissionController.Delete) // 删除权限
	utils.Get(permissionRouter, "/:id", permissionController.Detail)    // 查看权限详情

	adminUsersRouter := adminRouter.Group("/users")
	utils.Patch(adminUsersRouter, "/:id/attachRules", user.AttachRole) // 角色绑定权限

	adminUserRouter := adminRouter.Group("/user")
	utils.Get(adminUserRouter, "/", user.LoginUserInfo) // 用户信息
}
